/***************************************************************************
** 版权所有:   Copyright (c) 2020-2030
** 文件名称:  memory.c
** 当前版本:  v1.0
** 作    者:
** 完成日期: 2025-02-09
** 修改记录: 系统内存情况
** 修改日期:
** 版本号  :
** 修改人  :
** 修改内容:
***************************************************************************/

/*****************************头文件****************************************/
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/sched/task.h>
#include <linux/mm.h>
#include <linux/pid.h>
#include <linux/unistd.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched/signal.h>
#include <linux/sched/rt.h>
#include <linux/sched/deadline.h>
#include <linux/sysinfo.h>
#include <linux/mmzone.h> // 包含 vm_stat 的定义

/*****************************宏定义****************************************/

/*****************************结构体或类型定义*******************************/

/*****************************全局变量****************************************/

/*****************************本地变量****************************************/

/*****************************函数或类声明****************************************/

/*****************************函数或类实现****************************************/
#ifdef OPEN_SHOWMEMORY


// 打印系统当前的内存使用情况
int showmemory(const char *param)
{
    struct sysinfo si;

    // 获取系统内存信息
    si_meminfo(&si);

    // 打印系统内存使用情况
    printk(KERN_INFO "System Memory Usage:\n");
    printk(KERN_INFO "Total Memory: %lu KB (%lu MB, %lu GB)\n",
           si.totalram * si.mem_unit / 1024,
           si.totalram * si.mem_unit / (1024 * 1024),
           si.totalram * si.mem_unit / (1024 * 1024 * 1024));
    printk(KERN_INFO "Free Memory: %lu KB (%lu MB, %lu GB)\n",
           si.freeram * si.mem_unit / 1024,
           si.freeram * si.mem_unit / (1024 * 1024),
           si.freeram * si.mem_unit / (1024 * 1024 * 1024));
    printk(KERN_INFO "Buffer Memory: %lu KB (%lu MB, %lu GB)\n",
           si.bufferram * si.mem_unit / 1024,
           si.bufferram * si.mem_unit / (1024 * 1024),
           si.bufferram * si.mem_unit / (1024 * 1024 * 1024));

    // 获取缓存内存大小
    unsigned long cached_memory = global_node_page_state(NR_FILE_PAGES) * si.mem_unit / 1024;

    printk(KERN_INFO "Cache Memory: %lu KB (%lu MB, %lu GB)\n",
           cached_memory,
           cached_memory / 1024,
           cached_memory / (1024 * 1024));

    return 0;
}

#endif


// 打印每个进程的内存使用情况
int showprocessmemory(const char *param)
{
    struct task_struct *task;
    struct mm_struct *mm;
    unsigned long total_vm, resident_vm;

    // 打印标题
    printk(KERN_INFO "Process Memory Usage:\n");
    printk(KERN_INFO "%-10s%-30s%-10s%-10s\n", "PID", "Name", "Total VM", "Resident");

    // 遍历所有进程
    for_each_process(task)
    {
        mm = get_task_mm(task);
        if (!mm)
            continue;

        // 获取进程的内存使用信息
        total_vm = mm->total_vm;      // 总虚拟内存大小（以页面为单位）
        resident_vm = get_mm_rss(mm); // 常驻内存大小（以页面为单位）

        // 打印进程的内存使用情况
        printk(KERN_INFO "%-10d%-30s%-10lu%-10lu\n",
               task_pid_nr(task), task->comm, total_vm, resident_vm);

        // 释放 mm_struct 引用
        mmput(mm);
    }

    return 0;
}

// 打印每个线程的内存使用情况
int showthreadmemory(const char *param)
{
    struct task_struct *task, *thread;
    struct mm_struct *mm;
    unsigned long total_vm, resident_vm;

    // 打印标题
    printk(KERN_INFO "Thread Memory Usage:\n");
    printk(KERN_INFO "%-10s%-10s%-30s%-10s%-10s\n", "PID", "TID", "Name", "Total VM", "Resident");

    // 遍历所有进程
    for_each_process(task)
    {
        // 遍历当前进程的所有线程
        for_each_thread(task, thread)
        {
            mm = get_task_mm(thread);
            if (!mm)
                continue;

            // 获取线程的内存使用信息
            total_vm = mm->total_vm;      // 总虚拟内存大小（以页面为单位）
            resident_vm = get_mm_rss(mm); // 常驻内存大小（以页面为单位）

            // 打印线程的内存使用情况
            printk(KERN_INFO "%-10d%-10d%-30s%-10lu%-10lu\n",
                   task_pid_nr(task), task_pid_nr(thread), thread->comm, total_vm, resident_vm);

            // 释放 mm_struct 引用
            mmput(mm);
        }
    }

    return 0;
}

